package com.googlecode.perfectable.visuable.visual.custom;

import com.googlecode.perfectable.eventable.routing.Source;
import com.googlecode.perfectable.prosperable.message.ClientMessage;
import com.googlecode.perfectable.visuable.event.ButtonPushEvent;
import com.googlecode.perfectable.visuable.event.Event;
import com.googlecode.perfectable.visuable.event.EventListener;
import com.googlecode.perfectable.visuable.event.UnsupportedEvent;
import com.googlecode.perfectable.visuable.event.handler.ButtonPushEventHandler;
import com.googlecode.perfectable.visuable.renderer.ElementRenderer;
import com.googlecode.perfectable.visuable.renderer.VisualRenderer;
import com.googlecode.perfectable.visuable.visual.EventHandlingVisual;
import com.googlecode.perfectable.visuable.visual.IdentifiedVisuals;
import com.googlecode.perfectable.visuable.visual.MessageHandlingVisual;
import com.googlecode.perfectable.visuable.visual.TextualVisual;

public class ButtonVisual implements EventHandlingVisual, MessageHandlingVisual, TextualVisual {
	public static final String ELEMENT_NAME = "button";

	private final ButtonPushEventHandler pushHandler = ButtonPushEventHandler.create(this);

	private final String identifier;
	private String text;

	public ButtonVisual(String identifier, String text) {
		this.identifier = identifier;
		this.text = text;
	}

	public static ButtonVisual create(String identifier, String text) {
		return new ButtonVisual(identifier, text);
	}

	@Override
	public <E extends Event, L extends EventListener<E>> void registerEventListener(Class<E> eventClass, L listener)
			throws UnsupportedEvent {
		if(!ButtonPushEvent.class.isAssignableFrom(eventClass)) {
			throw new UnsupportedEvent();
		}
		@SuppressWarnings("unchecked")
		final EventListener<ButtonPushEvent> pushListener = (EventListener<ButtonPushEvent>) listener; // safe
		this.pushHandler.listen(pushListener);
	}

	@Override
	public void registerMessageHandlers(Source<ClientMessage> source) {
		source.listen(this.pushHandler);
	}

	@Override
	public void render(VisualRenderer painter) {
		try(ElementRenderer nestedPainter = painter.element(ELEMENT_NAME)) {
			IdentifiedVisuals.render(nestedPainter, this);
			nestedPainter.raw(this.text);
		}
	}

	@Override
	public String text() {
		return this.text;
	}

	@Override
	public void setText(String text) {
		this.text = text;
	}

	@SuppressWarnings("hiding")
	@Override
	public void appendText(String text) {
		this.text += text;
	}

	@Override
	public String identifier() {
		return this.identifier;
	}

}
